using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using NUtil.beans;

namespace NUtil.common {
    public class ToStringBuilder {
        private readonly object[] EMPTY_OBJECT_ARRAY = new object[0];

        public string ToStringProps(object obj) {
            if (null == obj) return string.Empty;
            return concatenatePropertyValues(obj, new List<PropertyInfo>(obj.GetType().GetProperties()));
        }

        public string ToStringFields(object obj) {
            if (null == obj) return string.Empty;
            FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
            return concatenateFieldValues(obj, new List<FieldInfo>(fields));
        }

        public string ToStringFields(object obj, String[] fieldNames) {
            if (null == obj) return string.Empty;
            return concatenateFieldValues(obj, BeanIntrospector.GetFieldsInclude(obj, fieldNames));
        }


        public string ToStringFieldsExclude(object obj, string[] fieldNames) {
            if (null == obj) return string.Empty;
            return concatenateFieldValues(obj, BeanIntrospector.GetFieldsExclude(obj, fieldNames));
        }

        public string ToStringPropsExclude(object obj, string[] propertiesToExclude) {
            if (null == obj) return string.Empty;
            return concatenatePropertyValues(obj, BeanIntrospector.GetPropertiesExclude(obj, propertiesToExclude));
        }

        public string ToStringProps(object obj, string[] propertiesToInclude) {
            if (null == obj) return string.Empty;
            return concatenatePropertyValues(obj, BeanIntrospector.GetPropertiesInclude(obj, propertiesToInclude));
        }

        private string concatenatePropertyValues(object obj, IList<PropertyInfo> properties) {
            StringBuilder stringBuilder = new StringBuilder();
            foreach (PropertyInfo info in properties) {
                if (stringBuilder.Length > 0) {
                    stringBuilder.Append(",");
                }
                stringBuilder.Append(info.Name).Append("->").Append(info.GetValue(obj, EMPTY_OBJECT_ARRAY));
            }
            return stringBuilder.ToString();
        }

        private string concatenateFieldValues(object obj, List<FieldInfo> fields) {
            StringBuilder stringBuilder = new StringBuilder();
            foreach (FieldInfo info in fields) {
                if (stringBuilder.Length > 0) {
                    stringBuilder.Append(",");
                }
                stringBuilder.Append(info.Name).Append("->").Append(info.GetValue(obj));
            }
            return stringBuilder.ToString();
        }
    }
}